package com.javasm.adminapi.module.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.javasm.adminapi.common.RedisKeys;
import com.javasm.adminapi.common.exception.ExceptionEnum;
import com.javasm.adminapi.common.exception.JavasmException;
import com.javasm.adminapi.login.model.LoginUser;
import com.javasm.adminapi.login.service.LoginService;
import com.javasm.adminapi.module.system.dao.UserDao;
import com.javasm.adminapi.module.system.dto.UserQueryDTO;
import com.javasm.adminapi.module.system.entity.Role;
import com.javasm.adminapi.module.system.entity.User;
import com.javasm.adminapi.module.system.service.PermissionService;
import com.javasm.adminapi.module.system.service.RoleService;
import com.javasm.adminapi.module.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户表(User)表服务实现类
 *
 * @author makejava
 * @since 2025-10-14 21:47:38
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    @Resource
    RedisTemplate<String,User> redisTemplate;




    @Override
    public boolean countRoleIds(List<Integer> arrayList) {
        if(arrayList!=null && arrayList.size()>0){
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(User::getUserRoleId,arrayList);
            return count(queryWrapper)==0;
        }
        throw new JavasmException(ExceptionEnum.Parameter_Null);
    }

    @Override
    public PageInfo<User> pageList(UserQueryDTO userQueryDTO) {
        Integer pageSize = userQueryDTO.getPageSize();
        Integer pageNum = userQueryDTO.getPageNum();
        PageHelper.startPage(pageNum,pageSize);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        String name = userQueryDTO.getName();
        if(!StringUtils.isEmpty( name)){
            queryWrapper.and(i->{
                i.like(User::getId,name);
                i.or();
                i.like(User::getUsername,name);
                i.or();
                i.like(User::getNickname,name);
            });
        }
        String phone = userQueryDTO.getPhone();
        if (!StringUtils.isEmpty(phone)){
            queryWrapper.and(i->{
                i.like(User::getPhone,phone);
                i.or();
                i.like(User::getEmail,phone);
            });
        }
        Integer type = userQueryDTO.getRoleId();
        if(type!=null){
            queryWrapper.eq(User::getUserRoleId,type);
        }
        Integer status = userQueryDTO.getStatus();
        if(status!=null){
            queryWrapper.eq(User::getStatus,status);
        }
        LocalDate start = userQueryDTO.getStart();
        LocalDate end = userQueryDTO.getEnd();
        if(!StringUtils.isEmpty(start)&&!StringUtils.isEmpty(end)){
            queryWrapper.and(i->{
                i.apply("date_format(create_time,'%Y-%m-%d') between {0} and {1}",start, end);
            });
        }
        queryWrapper.orderByDesc(User::getCreateTime);
        List<User> list = this.list(queryWrapper);
        PageInfo<User> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }
    @Resource
    PasswordEncoder passwordEncoder;
    @Override
    public void saveUpdate(User user) {
        if (user==null){
            throw new JavasmException(ExceptionEnum.Parameter_Null);
        }
        if (!StringUtils.isEmpty(user.getPassword())){
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        if(user.getId()==null){
            //添加逻辑
            if (checkUser(user)>0){
                throw new JavasmException(ExceptionEnum.User_Exist);
            }
            user.setCreateTime(new Date());
            user.setAvatarUrl("https://www.baidu.com/img/bd_logo1.png");
        }
        saveOrUpdate(user);
    }

    @Override
    public void delByIds(List<Long> collect) {
        List<User> list = listByIds(collect);
        removeRedisUser(list);
        removeByIds(collect);
    }

    @Override
    public void resetPassword(List<Long> collect) {
        //对id进行查询
        List<User> list = listByIds(collect);
        //将查出的数据进行修改密码
        list.stream().map(user -> {
            user.setPassword(passwordEncoder.encode("123456"));
            return user;
        }).collect(Collectors.toList());
        saveOrUpdateBatch(list);

    }

    @Override
    public void updateStatic(User user) {
        User user1 = getById(user.getId());
        user1.setStatus(user.getStatus());
        updateById(user1);
    }

    private void removeRedisUser(List<User> list) {
        for (User user : list) {
            String key = String.format(RedisKeys.WebUser_Name, user.getUsername());
            redisTemplate.delete(key);
        }
    }

    public Long checkUser(User user){
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername,user.getUsername());
        queryWrapper.or();
        queryWrapper.eq(User::getEmail,user.getEmail());
        queryWrapper.or();
        queryWrapper.eq(User::getPhone,user.getPhone());
        return count(queryWrapper);
    }

    @Override
    public User getByUsername(String username) {
        String key = String.format(RedisKeys.WebUser_Name, username);
        return getUser(key,"username",username);
    }


    @Autowired
    RoleApiServiceImpl roleService;
    private User getUser(String key,String col,String word){

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername,word);
        User user = this.getOne(queryWrapper);
        if(user!=null){
            Role role = roleService.getByRid(user.getUserRoleId());
            user.setRole(role);
        }


//        User user = redisTemplate.opsForValue().get(key);
//        if(user!=null){
//            return user;
//        }
//
//        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(User::getUsername,word);
//        user = this.getOne(queryWrapper);
//        if(user!=null){
//            Role role = roleService.getByRid(user.getUserRoleId());
//            user.setRole(role);
//            redisTemplate.opsForValue().set(key,user,5, TimeUnit.DAYS);
//        }else{
//            user = new User();
//            redisTemplate.opsForValue().set(key,null,5, TimeUnit.MINUTES);
//        }


        return user;
    }




}
